﻿//-----------------------------------------------------------------------
// <copyright file="ResultsPerPageSearchCoreResults.cs" company="Microsoft Services | Global delivery">
// Copyright (c) Microsoft Services | Global delivery.
// All rights reserved.
// THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY 
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
// </copyright>
// <date>15-May-2012</date>
// <summary>This class implements the Results Per Page Search Core Results.</summary>
//----------------------------------------------------------------------- 

namespace Microsoft.Services.SP.WebParts
{
    using System;
    using System.Collections.Generic;
    using System.Collections.Specialized;
    using System.ComponentModel;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Web.UI.WebControls.WebParts;

    using Microsoft.Office.Server.Search;
    using Microsoft.Office.Server.Search.WebControls;
    using Microsoft.SharePoint;
    using Microsoft.SharePoint.WebControls;
    using Microsoft.SharePoint.WebPartPages;

    /// <summary>
    /// This class implements the Results Per Page Search Core Results.
    /// </summary>
    [ToolboxItemAttribute(false)]
    public class ResultsPerPageSearchCoreResults : CoreResultsWebPart
    {
        /// <summary>
        /// Constant for default value for numeric fields.
        /// </summary>
        public const int DEFAULTVALUE = 10;

        /// <summary>
        /// Panel that acts as the container.
        /// </summary>
        private Panel pnl;

        /// <summary>
        /// Label for displaying the title.
        /// </summary>
        private Label lbl;

        /// <summary>
        /// Drop down list to show the list of results per page.
        /// </summary>
        private DropDownList ddlist;

        /// <summary>
        /// The HTTP context of the page.
        /// </summary>
        private HttpContext context;

        /// <summary>
        /// Custom query param for implementing results per page.
        /// </summary>
        private string hits;

        /// <summary>
        /// Enable results per page.
        /// </summary>
        private bool enableResultsPerPage = true;

        /// <summary>
        /// Incremental value to display for results per page.
        /// </summary>
        private int incrementValue = 10;

        /// <summary>
        /// Maximum limit for results per page.
        /// </summary>
        private int maximumLimit = 50;

        /// <summary>
        /// Results per page custom title.
        /// </summary>
        private string resultsPerPageTitle = "Results per page";

        /// <summary>
        /// Gets or sets a value indicating whether [enable results per page].
        /// </summary>
        /// <value>
        /// <c>true</c> if [enable results per page]; otherwise, <c>false</c>.
        /// </value>
        [WebBrowsable(true), Category("Miscellaneous"), DefaultValue(true),
        FriendlyName("Enable Results Per Page"), Personalizable(PersonalizationScope.Shared),
        Description("Enable the results per page functionality."), WebPartStorage(Storage.Shared)]
        public bool EnableResultsPerPage
        {
            get
            {
                return this.enableResultsPerPage;
            }

            set
            {
                this.enableResultsPerPage = value;
            }
        }

        /// <summary>
        /// Gets or sets the increment value.
        /// </summary>
        /// <value>
        /// The increment value.
        /// </value>
        [WebBrowsable(true), Category("Miscellaneous"), DefaultValue(DEFAULTVALUE),
        FriendlyName("Increment Value"), Personalizable(PersonalizationScope.Shared),
        Description("Incremental value to display for results per page."), WebPartStorage(Storage.Shared)]
        public int IncrementValue
        {
            get
            {
                return this.incrementValue;
            }

            set
            {
                if (value == 0)
                {
                    this.incrementValue = DEFAULTVALUE;
                }
                else
                {
                    this.incrementValue = value;
                }
            }
        }

        /// <summary>
        /// Gets or sets the maximum limit.
        /// </summary>
        /// <value>
        /// The maximum limit.
        /// </value>
        [WebBrowsable(true), Category("Miscellaneous"), DefaultValue(50),
        FriendlyName("Maximum Limit"), Personalizable(PersonalizationScope.Shared),
        Description("Maximum limit to display for results per page."), WebPartStorage(Storage.Shared)]
        public int MaximumLimit
        {
            get
            {
                return this.maximumLimit;
            }

            set
            {
                if (value == 0)
                {
                    this.maximumLimit = DEFAULTVALUE;
                }
                else
                {
                    this.maximumLimit = value;
                }
            }
        }

        /// <summary>
        /// Gets or sets the results per page title.
        /// </summary>
        /// <value>
        /// The results per page title.
        /// </value>
        [WebBrowsable(true), Category("Miscellaneous"), DefaultValue("Results per page"),
        FriendlyName("Results Per Page Title"), Personalizable(PersonalizationScope.Shared),
        Description("Title for results per page drop down list."), WebPartStorage(Storage.Shared)]
        public string ResultsPerPageTitle
        {
            get
            {
                return this.resultsPerPageTitle;
            }

            set
            {
                this.resultsPerPageTitle = value;
            }
        }

        /// <summary>
        /// Configures the data source properties.
        /// </summary>
        protected override void ConfigureDataSourceProperties()
        {
            base.ConfigureDataSourceProperties();

            if (this.enableResultsPerPage)
            {
                CoreResultsDatasource dataSource = this.DataSource as CoreResultsDatasource;

                this.context = this.Context;
                this.hits = this.context.Request.Params.Get("hits");

                int hitValue = 0;
                if (!string.IsNullOrEmpty(this.hits) && Int32.TryParse(this.hits, out hitValue))
                {
                    dataSource.ResultsPerPage = hitValue;
                }
            }
        }

        /// <summary>
        /// This member is reserved for internal use and is not intended to be used directly from your code.
        /// </summary>
        protected override void CreateChildControls()
        {
            if (this.enableResultsPerPage)
            {
                try
                {
                    CssRegistration.Register("/_layouts/ResultsPerPageSearchCoreResults/styles.css");

                    this.pnl = new Panel();
                    this.pnl.CssClass = "srch-results resultsperpagepanel";

                    this.lbl = new Label();
                    this.lbl.Text = this.ResultsPerPageTitle;
                    this.lbl.CssClass = "resultsperpagetitle";

                    this.ddlist = new DropDownList();
                    this.ddlist.CssClass = "resultsperpagelist";
                    this.ddlist.AutoPostBack = true;
                    this.ddlist.SelectedIndexChanged += new EventHandler(this.DDList_SelectedIndexChanged);

                    int counter = this.IncrementValue;
                    for (int i = 0; i < (this.MaximumLimit / this.IncrementValue); i++)
                    {
                        this.ddlist.Items.Add(counter.ToString());
                        counter += this.IncrementValue;
                    }

                    this.pnl.Controls.Add(this.lbl);
                    this.pnl.Controls.Add(this.ddlist);
                    this.Controls.Add(this.pnl);

                    if (!string.IsNullOrEmpty(this.hits))
                    {
                        this.ddlist.SelectedValue = this.hits;
                    }
                    else
                    {
                        this.ddlist.SelectedValue = this.ResultsPerPage.ToString();
                    }
                }
                catch
                {
                    throw;
                }
            }

            base.CreateChildControls();
        }

        /// <summary>
        /// Handles the SelectedIndexChanged event of the DDList control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        protected void DDList_SelectedIndexChanged(object sender, EventArgs e)
        {
            NameValueCollection queryParams = new NameValueCollection(this.context.Request.QueryString); ////HttpUtility.ParseQueryString(context.Request.QueryString);

            if (!string.IsNullOrEmpty(this.hits))
            {
                queryParams.Set("hits", ((DropDownList)sender).SelectedValue);
            }
            else
            {
                queryParams.Add("hits", ((DropDownList)sender).SelectedValue);
            }

            this.context.Response.Redirect(this.context.Request.Url.GetLeftPart(UriPartial.Path) + "?" + this.ConstructQueryString(queryParams));
        }

        /// <summary>
        /// Constructs the query string.
        /// </summary>
        /// <param name="parameters">The parameters.</param>
        /// <returns>Returns the constructed query string.</returns>
        private string ConstructQueryString(NameValueCollection parameters)
        {
            List<string> items = new List<string>();
            foreach (string name in parameters)
            {
                items.Add(string.Concat(name, "=", System.Web.HttpUtility.UrlEncode(parameters[name])));
            }

            return string.Join("&", items.ToArray());
        }
    }
}
